package com.hn658.base.message.appinfo.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.hn658.base.message.account.service.IAccountUserManagerService;
import com.hn658.base.message.app.service.IAppInfoManager;
import com.hn658.base.message.appinfo.dao.db.IAppInfoDBDAO;
import com.hn658.base.message.appinfo.dao.redis.IAppInfoRedisDAO;
import com.hn658.base.message.appinfo.entity.AppInfoEO;
import com.hn658.base.message.appinfo.exception.AppInfoException;
import com.hn658.base.message.appinfo.service.IAppInfoService;
import com.hn658.base.message.common.contants.MessageContants;
import com.hn658.framework.common.AbstractBusinessObject;
import com.hn658.framework.dataaccess.pagination.GenericPage;
import com.hn658.framework.logging.enums.LogCategory;
import com.hn658.framework.shared.exception.BusinessException;
import com.hn658.message.filemgmt.service.IFileManager;
import com.hn658.user.itf.vo.AppInfoDTO;


/**
 * 应用业务逻辑实现类
 * 
 * @author ztjie
 * 
 */
@Service
public class AppInfoServiceImpl extends AbstractBusinessObject implements
		IAppInfoService {

	@Autowired
	private IAppInfoDBDAO appInfoDBDAO;

	@Autowired
	private IAppInfoRedisDAO appInfoRedisDAO;
	
	@Autowired
	private IFileManager fileManger;
	
	@Autowired
	private IAppInfoManager appInfoManager;

	@Autowired
	private IAccountUserManagerService accountUserManagerService;
	
	@Override
	public List<AppInfoEO> findAppInfosByIds(List<Long> ids) {
		return appInfoDBDAO.selectByIds(ids);
	}
	
	@Override
	public GenericPage<AppInfoEO> queryAppInfo(Map<String, Object> queryMap,
			int limit, int start, String sortBy, boolean isAsc) {
		if (StringUtils.isEmpty(sortBy)) {
			sortBy = "ID";
		}
		return appInfoDBDAO.selectByMap(queryMap, limit, start, sortBy, isAsc);
	}

	@Override
	@Transactional
	public AppInfoEO addApp(AppInfoEO appInfo,byte[] apnsPaths) throws AppInfoException {
		if (appInfo == null) {
			throw new AppInfoException(AppInfoException.AppInfoEmpty);
		}
		if (StringUtils.isBlank(appInfo.getAppName())) {
			throw new AppInfoException(AppInfoException.AppNameEmpty);
		}
		if (StringUtils.isBlank(appInfo.getApnsPassword())) {
			throw new AppInfoException("证书密码不能为空");
		}
		if (StringUtils.isBlank(appInfo.getBaiduApiKey())) {
			throw new AppInfoException("百度云key不能为空");
		}
		if (StringUtils.isBlank(appInfo.getBaiduSecretKey())) {
			throw new AppInfoException("百度云秘钥不能为空");
		}
		if (appInfoDBDAO.selectUniqueByProp("appId",appInfo.getAppId()) != null) {
			throw new AppInfoException(AppInfoException.AppHadRegister);
		}
		appInfo.setAppName(StringUtils.trim(appInfo.getAppName()));
		if(apnsPaths !=null&&apnsPaths.length !=0){
			String saveBackendFileAvatar = fileManger.saveBackendFileAvatar(apnsPaths, appInfo.getAppId());
			appInfo.setApnsPath(saveBackendFileAvatar);
		}
		if (StringUtils.isBlank(appInfo.getApnsPath())) {
			throw new AppInfoException("证书路径不能为空");
		}
		appInfo.setIsDeleted(false);
		appInfo.setCreateTime(new Date());
		appInfo.setLastUpdateTime(new Date());
		
		AppInfoDTO appInfoDTO = appInfoManager.findAppInfoByAppId(appInfo.getAppId());
		
		appInfoDBDAO.insert(appInfo);
		//创建系统通知用户
		accountUserManagerService.createToken(
				appInfoDTO.getAppId(), 
				MessageContants.SYSTEM_USER_ID+"", appInfoDTO.getAppName(), appInfoDTO.getLogUrl());
		return appInfo;
	}

	@Override
	public AppInfoEO findAppByAppId(String appId) throws AppInfoException {
		// 先从Redis中查询应用信息
		AppInfoEO appInfo = appInfoRedisDAO.findAppByAppId(appId);
		// 如Redis中为找到对应应用信息，则尝试去DB中查找
		if (null == appInfo) {
			logger.debug(LogCategory.USER, "在redis中未找到{}相关信息，尝试在数据库中查找。", appId);
			appInfo = appInfoDBDAO.selectUniqueByProp("appId",
					appId);

			// 如过在DB中找到对应信息返回，并将信息存入Redis中
			if (null != appInfo) {
				logger.debug(LogCategory.USER, "在数据库中查找到{}相关信息，重新讲该信息存储到Redis。", appId);
				appInfoRedisDAO.saveApp(appInfo);
			}
		} else {
			logger.debug(LogCategory.USER, "成功的在redis中找到{}相关信息。", appId);
		}

		return appInfo;
	}

	@Override
	public AppInfoEO findAppById(Long id) throws AppInfoException{
		if(id==null){
			throw new BusinessException(AppInfoException.AppIdEmpty);
		}
		// 先从Redis中查询应用信息
		AppInfoEO appInfo = appInfoRedisDAO.findAppById(id);

		// 如Redis中为找到对应应用信息，则尝试去DB中查找
		if (null == appInfo) {
			logger.debug(LogCategory.USER, "在redis中未找到{}相关信息，尝试在数据库中查找。", id);
			appInfo = appInfoDBDAO.selectById(Long.valueOf(id));
			// 如过在DB中找到对应信息返回，并将信息存入Redis中
			if (null != appInfo) {
				logger.debug(LogCategory.USER, "在数据库中查找到{}相关信息，重新讲该信息存储到Redis。", id);
				appInfoRedisDAO.saveApp(appInfo);
			}
		} else {
			logger.debug(LogCategory.USER, "成功的在redis中找到{}相关信息。", id);
		}
		return appInfo;
	}

	@Override
	public boolean deleteAppById(Long Id) throws AppInfoException {
		if(null==Id){
			throw new AppInfoException(AppInfoException.AppIdEmpty);	
		}
		if(1==appInfoDBDAO.deleteById(Id)){
			return true;
		}
		return false;
	}

	@Override
	public void disableAppInfo(Long id) throws  AppInfoException {
		if(StringUtils.isEmpty(String.valueOf(id))){
			throw new BusinessException(AppInfoException.AppIdEmpty);
		}
		AppInfoEO appInfoEO=appInfoDBDAO.selectById(id);
		if(null==appInfoEO){
			throw new BusinessException(AppInfoException.AppInfoEmpty);
		}
		appInfoEO.setIsDeleted(true);
		appInfoDBDAO.update(appInfoEO);
		appInfoRedisDAO.deleteApp(id);
	}

	@Override
	public void enableAppInfo(Long id) throws AppInfoException {
		if(StringUtils.isEmpty(String.valueOf(id))){
			throw new BusinessException(AppInfoException.AppIdEmpty);
		}
		AppInfoEO appInfoEO=appInfoDBDAO.selectById(id);
		if(null==appInfoEO){
			throw new BusinessException(AppInfoException.AppInfoEmpty);
		}
		appInfoEO.setIsDeleted(false);
		appInfoDBDAO.update(appInfoEO);
		appInfoRedisDAO.deleteApp(id);
	}

	@Override
	public AppInfoEO modifyAppInfo(AppInfoEO appInfo,byte[] apnsUpload) throws AppInfoException{
		if (appInfo == null) {
			throw new AppInfoException(AppInfoException.AppInfoEmpty);
		}
		if(StringUtils.isBlank(appInfo.getId().toString())){
			throw new AppInfoException("id不能为空");
		}
		AppInfoEO dbAppInfo = appInfoDBDAO.selectById((Long) appInfo.getId());

		if (StringUtils.isNotBlank(appInfo.getAppId())) {
			dbAppInfo.setAppId(appInfo.getAppId());
		}
		if (StringUtils.isNotBlank(appInfo.getAppName())) {
			//若应用名称不为空，则检查数据库中是否已经存在同名应用，若存在则抛出异常
			AppInfoEO appInfo2=appInfoDBDAO.selectUniqueByProp("appName",
					StringUtils.trim(appInfo.getAppName())) ;
		    if(null!=appInfo2){
		    	Map<String,Object> params=new HashMap<String, Object>();
		    	params.put("appName", appInfo.getAppName());
		    	int countByName=appInfoDBDAO.countByMap(params);
	            if(!appInfo2.getId().equals(appInfo.getId())){
	            	if(countByName>0){
	            		throw new AppInfoException(AppInfoException.AppHadRegister);
	            	}
	            }else{
	            	if(countByName>1){
	            		throw new AppInfoException(AppInfoException.AppHadRegister);
	            	}
	            }
		            
		    }
			dbAppInfo.setAppName(appInfo.getAppName());
		}
		if (StringUtils.isNotBlank(appInfo.getDescInfo())) {
			dbAppInfo.setDescInfo(appInfo.getDescInfo());
		}
		
		if (StringUtils.isNotBlank(String.valueOf(appInfo.getIsDeleted()))) {
			dbAppInfo.setIsDeleted(appInfo.getIsDeleted());
			
		}
		if (StringUtils.isBlank(appInfo.getApnsPassword())) {
			throw new AppInfoException("证书密码不能为空");
		}
		if (StringUtils.isBlank(appInfo.getBaiduApiKey())) {
			throw new AppInfoException("百度云key不能为空");
		}
		if (StringUtils.isBlank(appInfo.getBaiduSecretKey())) {
			throw new AppInfoException("百度云秘钥不能为空");
		}
		appInfo.setAppName(StringUtils.trim(appInfo.getAppName()));
		if(apnsUpload !=null&&apnsUpload.length !=0){
			String saveBackendFileAvatar = fileManger.saveBackendFileAvatar(apnsUpload, appInfo.getAppId());
			dbAppInfo.setApnsPath(saveBackendFileAvatar);
		}
		if (StringUtils.isBlank(appInfo.getApnsPath())) {
			throw new AppInfoException("证书路径不能为空");
		}
		dbAppInfo.setApnsPassword(appInfo.getApnsPassword());
		dbAppInfo.setBaiduApiKey(appInfo.getBaiduApiKey());
		dbAppInfo.setBaiduSecretKey(appInfo.getBaiduSecretKey());
		dbAppInfo.setLastUpdateTime(new Date());
		appInfoDBDAO.update(dbAppInfo);
		appInfoRedisDAO.deleteApp(appInfo.getId());
		return dbAppInfo;
		
	}

	@Override
	public AppInfoEO findAppBaiduConfig(String appId) throws AppInfoException {
		if(StringUtils.isEmpty(appId)){
			throw new AppInfoException(AppInfoException.AppIdEmpty);
		}
		AppInfoEO appInfo = this.findAppByAppId(appId);
        if(appInfo==null){
        	throw new AppInfoException(AppInfoException.AppInfoEmpty);
        }
        if(StringUtils.isEmpty(appInfo.getBaiduApiKey())||StringUtils.isEmpty(appInfo.getBaiduSecretKey())){
        	throw new AppInfoException(AppInfoException.AppNoBaiduConfig);
        }
        return appInfo;
	}

	@Override
	public AppInfoEO findAppApnsConfig(String appId) throws AppInfoException {
		if(StringUtils.isEmpty(appId)){
			throw new AppInfoException(AppInfoException.AppIdEmpty);
		}
		AppInfoEO appInfo = this.findAppByAppId(appId);
        if(appInfo==null){
        	throw new AppInfoException(AppInfoException.AppInfoEmpty);
        }
        if(StringUtils.isEmpty(appInfo.getApnsPath())||StringUtils.isEmpty(appInfo.getApnsPassword())){
        	throw new AppInfoException(AppInfoException.AppNoApnsConfig);
        }
        return appInfo;
	}
	
	
	
}
